{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# hvPlot.vectorfield\n",
    "\n",
    "```{eval-rst}\n",
    ".. currentmodule:: hvplot\n",
    "\n",
    ".. automethod:: hvPlot.vectorfield\n",
    "```\n",
    "\n",
    "## Backend-specific styling options\n",
    "\n",
    "```{eval-rst}\n",
    ".. backend-styling-options:: vectorfield\n",
    "```\n",
    "\n",
    "## Examples\n",
    "\n",
    "### Basic vectorfield plot\n",
    "\n",
    "In this example we create a simple DataFrame with 4 columns `x`, `y`, `angle` and `mag`. `x` and `y` represent the pivot point of the vectors/arrows which is by default defined to be in the middle, demonstrated by overlaid points plot. `angle` defines the arrow direction expressed in radian. `mag` defines how long the arrows should be; the magnitudes are rescaled by default to the minimum distance between individual arrows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "df = pd.DataFrame(dict(\n",
    "    x=[-1, 0, 1, 0],\n",
    "    y=[0, -1, 0, 1],\n",
    "    angle=[0, np.pi/2, np.pi, 3*np.pi/2],\n",
    "    mag=[2, 4, 6, 8],\n",
    "))\n",
    "\n",
    "df.hvplot.points(x=\"x\", y=\"y\", frame_width=200) *\\\n",
    "df.hvplot.vectorfield(\n",
    "    x=\"x\", y=\"y\", angle=\"angle\", mag=\"mag\",\n",
    "    data_aspect=1, padding=0.4, frame_width=200,\n",
    ").opts(magnitude=\"mag\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Xarray example\n",
    "\n",
    "In this example we also set the [`color`](option-color) to the magnitude variable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.xarray  # noqa\n",
    "import numpy as np\n",
    "import xarray as xr\n",
    "\n",
    "def sample_data(shape=(20, 30)):\n",
    "    x = np.linspace(311.9, 391.1, shape[1])\n",
    "    y = np.linspace(-23.6, 24.8, shape[0])\n",
    "    x2d, y2d = np.meshgrid(x, y)\n",
    "    u = 10 * (2 * np.cos(2 * np.deg2rad(x2d) + 3 * np.deg2rad(y2d + 30)) ** 2)\n",
    "    v = 20 * np.cos(6 * np.deg2rad(x2d))\n",
    "    return x, y, u, v\n",
    "\n",
    "xs, ys, U, V = sample_data()\n",
    "mag = np.sqrt(U**2 + V**2)\n",
    "angle = (np.pi/2.) - np.arctan2(U/mag, V/mag)\n",
    "ds = xr.Dataset({\n",
    "    'mag': xr.DataArray(mag, dims=('y', 'x'), coords={'y': ys, 'x': xs}),\n",
    "    'angle': xr.DataArray(angle, dims=('y', 'x'), coords={'y': ys, 'x': xs})\n",
    "})\n",
    "\n",
    "ds.hvplot.vectorfield(\n",
    "    x='x', y='y', angle='angle', mag='mag',\n",
    "    color='mag', cmap='viridis', colorbar=True,\n",
    ").opts(magnitude='mag')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Geographic example with Xarray\n",
    "\n",
    "The `xarray.Dataset` constructed in this example has a `'crs'` key in its `attrs` dictionary, which lets us simply set `geo=True` to turn this plot into a correctly projected geographic plot overlaid on web map tiles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cartopy.crs as ccrs\n",
    "import hvplot.xarray  # noqa\n",
    "import numpy as np\n",
    "import xarray as xr\n",
    "\n",
    "def sample_data(shape=(20, 30)):\n",
    "    \"\"\"\n",
    "    Return ``(x, y, u, v, crs)`` of some vector data computed mathematically.\n",
    "    The returned crs will be a rotated pole CRS, meaning that the vectors\n",
    "    will be unevenly spaced in regular PlateCarree space.\n",
    "    \"\"\"\n",
    "    crs = ccrs.RotatedPole(pole_longitude=177.5, pole_latitude=37.5)\n",
    "\n",
    "    x = np.linspace(311.9, 391.1, shape[1])\n",
    "    y = np.linspace(-23.6, 24.8, shape[0])\n",
    "    x2d, y2d = np.meshgrid(x, y)\n",
    "    u = 10 * (2 * np.cos(2 * np.deg2rad(x2d) + 3 * np.deg2rad(y2d + 30)) ** 2)\n",
    "    v = 20 * np.cos(6 * np.deg2rad(x2d))\n",
    "    return x, y, u, v, crs\n",
    "\n",
    "xs, ys, U, V, crs = sample_data()\n",
    "mag = np.sqrt(U**2 + V**2)\n",
    "angle = (np.pi/2.) - np.arctan2(U/mag, V/mag)\n",
    "ds = xr.Dataset(\n",
    "    {\n",
    "        'mag': xr.DataArray(mag, dims=('y', 'x'), coords={'y': ys, 'x': xs}),\n",
    "        'angle': xr.DataArray(angle, dims=('y', 'x'), coords={'y': ys, 'x': xs})\n",
    "    },\n",
    "    attrs={'crs': crs},\n",
    ")\n",
    "\n",
    "ds.hvplot.vectorfield(\n",
    "    x=\"x\", y=\"y\", angle=\"angle\", mag=\"mag\",\n",
    "    geo=True, tiles=\"CartoLight\"\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
